import com.makinolo.rlvforge.*;
import com.makinolo.rlvforge.components.*;

import flash.events.Event;
import flash.events.MouseEvent;
import flash.filesystem.File;
import flash.net.FileFilter;

import mx.charts.HitData;
import mx.charts.chartClasses.IAxis;
import mx.charts.series.*;
import mx.collections.ArrayCollection;
import mx.events.*;
import mx.formatters.NumberBase;
import mx.managers.CursorManager;
import mx.managers.PopUpManager;
  	
private var pdata:ProjectData;

[Bindable]
private var profilevalues:ArrayCollection;
[Bindable]
private var gridvalues:ArrayCollection;
[Bindable]
private var timelineData:ArrayCollection;

[Bindable]
private var selstart:Number;
[Bindable]
private var selend:Number;

private var np:NewProjectDialog

private const CURRENT_ROW_COLOR:int = 0x252525;
private const HUGESLOPECHANGE_ROW_COLOR:int = 0xeb4646;
private const MODERATESLOPECHANGE_ROW_COLOR:int = 0xeaf629;
private const STEEPSLOPE_ROW_COLOR:int = 0xff0000;
private const SELECTED_ROW_COLOR:int = 0x2572a7;
		
public function init():void
{			
	selstart = -1;
	selend = -1;
	timelineData = new ArrayCollection();
	timelineData.addItem({distance:0, elevation:0});
	timelineData.addItem({distance:0, elevation:0});	
	menuData.addEventListener(MenuEvent.ITEM_CLICK, menuClick);
	videoplayer.addEventListener(VideoEvent.SEEKING, this.onVideoUpdate);
	videoplayer.addEventListener(VideoEvent.PLAYHEAD_UPDATE, this.onVideoUpdate);
	videoplayer.addEventListener(VideoEvent.STATE_CHANGE, this.vidStateChange)
	videoplayer.addEventListener(VideoEvent.COMPLETE, this.onVideoComplete)
	profilechart.addEventListener(MouseEvent.MOUSE_WHEEL, this.onChangeProfileScale);
	profile.addEventListener(MouseEvent.CLICK, this.onClickOnProfile);
}

public function getPdata():ProjectData
{
	return this.pdata;
}

public function getVideoPlayer():VideoProfile
{
	return this.videoplayer;
}

private function onPlayButton():void
{
	if (!videoplayer.playing)
	{
		startPlaying();	
	}
	else
	{
		pausePlaying();
	}
}

public function startPlaying():void
{
	videoplayer.play();
	playButton.label = "||";	
}
public function pausePlaying():void
{
	videoplayer.pause();
	playButton.label = ">";
}

private function onSliderChange(event:Event):void
{		
	pausePlaying();
	trace("moviendo slider a posicion ="+event.currentTarget.value);
	videoplayer.playheadTime = event.currentTarget.value;
	// Cuando nos movemos al final del video no podemos reposicionar la 
	// playhead porque para eso tendría que tener un keyframe en el ultimo frame
	// quizas es algo que hay que tener en cuenta al codificar los videos.	
}

// Como no podemos posicionarnos en momentos del video exactos si no 
// son keyframes, no podemos avanzar o retroceder tiempos concretos
// La unica solucion es que el video esté codificado con GOP = Framerate
// habitualmente 25, para que pueda saltar de segundo en segundo
private function secForward():void
{	
	var newtime:Number = Math.floor(videoplayer.playheadTime+1);
	if (newtime>videoplayer.totalTime)
		newtime = videoplayer.totalTime;
	videoplayer.playheadTime = newtime;
	
	pausePlaying();
}
private function secBack():void
{
	var newtime:Number = Math.floor(videoplayer.playheadTime-2.1);
	if (newtime<0)
		newtime = 0;
	videoplayer.playheadTime = newtime;
	pausePlaying();	
}


public function menuClick(e:MenuEvent):void
{	
	var file:File;
	if (e.item.@menuid == "newprj")
	{
		np = new NewProjectDialog();
		PopUpManager.addPopUp(np, this, true);
        PopUpManager.centerPopUp(np);
		np.addEventListener(CloseEvent.CLOSE, newPrjWindow_close);
	}
	else if (e.item.@menuid == "openprj")
	{
		closeProcedure();
		file = new File();
		file.addEventListener(Event.SELECT, fileOpenSelected);			
 		file.browseForOpen("Open project", [new FileFilter("FineTuner Projects (.prf)", "*.prf")]); 		 			 
 	}
 	else if (e.item.@menuid == "saveprj")
 	{
 		if(this.pdata!=null)
 		{ 			
 			if (this.pdata.hasFile())
 			{
 				CursorManager.setBusyCursor();
 				this.pdata.save();
				CursorManager.removeBusyCursor();	 				
 			}
 			else
 			{
 				file = new File();
				file.addEventListener(Event.SELECT, fileSaveSelected);			
 				file.browseForSave("Save Project");
 			} 					
 		} 		
 	}
 	else if (e.item.@menuid == "closeprj")
 	{
 		closeProcedure();
 	}
 	else if(e.item.@menuid == "prjproperties")
 	{
 		np = new NewProjectDialog();
 		PopUpManager.addPopUp(np, this, true);
 		np.flvfilepath.text = this.pdata.getVideoPath();
		np.gpxfilepath.text = this.pdata.getGPSPath();
		np.prjname.text = this.pdata.getStageName();
		np.prjdesc.text = this.pdata.getStageDesc();
		np.createButton.label = "OK";
		np.createButton.enabled = true;
        PopUpManager.centerPopUp(np);
		np.addEventListener(CloseEvent.CLOSE, propertiesPrjWindow_close);
 	}
 	else if (e.item.@menuid == "exit")
	{
		var exitingEvent:Event = new Event(Event.EXITING, false, true);
    	NativeApplication.nativeApplication.dispatchEvent(exitingEvent);
    	if (!exitingEvent.isDefaultPrevented()) 
    	{
        	NativeApplication.nativeApplication.exit();
    	}
	}
 	else if (e.item.@menuid == "exportprj")
	{
		if (this.pdata != null)
			this.pdata.export();
	}
	else if (e.item.@menuid == "exportgpxprj")
	{
		if (this.pdata != null)
			this.pdata.exportGPX();
	}
	else if (e.item.@menuid == "exportpb")
	{
		if (this.pdata != null)
			this.pdata.exportSessionDefinitionPB();
	}	
	else if (e.item.@menuid == "coursestart")
	{
		if (this.pdata != null)
		{			
			var wayptwindow:WayPointEditor = new WayPointEditor();
			PopUpManager.addPopUp(wayptwindow, this, true);
        	PopUpManager.centerPopUp(wayptwindow);
        	wayptwindow.title = "Course Starting Point";
        	wayptwindow.namelabel.text = "Name "
        	wayptwindow.type = "SEGSTART";
			wayptwindow.addEventListener(CloseEvent.CLOSE, wayPointWindow_close);
		}
	}
	else if(e.item.@menuid == "courseend")
	{
		if (this.pdata != null)
		{
			// TODO: Falta por cambiar el aspecto de este diálogo para que presente una lista
			// con todos los SEGSTART para elegir el que queremos cerrar
			var wayptwindow:WayPointEditor = new WayPointEditor();
			PopUpManager.addPopUp(wayptwindow, this, true);
        	PopUpManager.centerPopUp(wayptwindow);
        	wayptwindow.title = "Course End Point";
        	wayptwindow.namelabel.text = "Name "
        	wayptwindow.description.visible = false;
        	wayptwindow.desclabel.visible = false;
        	wayptwindow.type = "SEGEND";
			wayptwindow.addEventListener(CloseEvent.CLOSE, wayPointWindow_close);
		}
	}
	else if(e.item.@menuid == "infobox")
	{
		if (this.pdata != null)
		{		
			var gp:GISPoint = this.pdata.getCurrentGISPoint(this.videoplayer.playheadTime);	
			var wayptwindow:WayPointEditor = new WayPointEditor();
			PopUpManager.addPopUp(wayptwindow, this, true);
	        PopUpManager.centerPopUp(wayptwindow);
	        wayptwindow.title = "Information box";
	        wayptwindow.type = "INFOBOX";
	        wayptwindow.namelabel.visible = false;
	        wayptwindow.wptname.visible = false;
	        wayptwindow.description.text = "Elevation "+gp.getElev();
	        wayptwindow.addEventListener(CloseEvent.CLOSE, wayPointWindow_close);
		}
	}
}

private function closeProcedure():void
{
	this.pdata = null;	
	if (this.videoplayer.source != null)
		this.videoplayer.clear();
	map.close();
	profilevalues = null;	
	gridvalues = null;
	// Disable buttons
	secback.enabled = false;
	secforw.enabled = false;
	selst.enabled = false;
	selcl.enabled = false;
	selall.enabled = false;
	playButton.enabled = false;	
	videoslider.enabled = false;
	smoothbtn.enabled = false;
	fixbtn.enabled = false;
	filterbtn.enabled = false;
	getelevation.enabled = false;
	// Disable Menus
	menuData.dataProvider[0].menuitem[2].@enabled=false;
	menuData.dataProvider[0].menuitem[3].@enabled=false;
	menuData.dataProvider[0].menuitem[4].@enabled=false;
	menuData.dataProvider[0].menuitem[5].@enabled=false;
	menuData.dataProvider[0].menuitem[5].menuitem[0].@enabled=false;
	menuData.dataProvider[0].menuitem[5].menuitem[1].@enabled=false;
	menuData.dataProvider[0].menuitem[5].menuitem[2].@enabled=false;
	menuData.dataProvider[0].menuitem[6].@enabled=false;
	menuData.dataProvider[1].menuitem[0].@enabled=false;
	menuData.dataProvider[1].menuitem[1].@enabled=false;
	menuData.dataProvider[1].menuitem[2].@enabled=false;
}

private function newPrjWindow_close(evt:CloseEvent):void
{	
	if (np.gpxfilepath.text != "" && np.flvfilepath.text!="")
	{
		this.pdata = new ProjectData();
		this.pdata.create(this.videoplayer, np.flvfilepath.text, np.gpxfilepath.text, np.trackType, np.prjname.text, np.prjdesc.text);
		this.pdata.addEventListener("PRJLoaded", projectLoaded);
		this.pdata.addEventListener("TimeGapsFound", onTimeGapsDetected);		
	}
	PopUpManager.removePopUp(np);
}

private function propertiesPrjWindow_close(evt:CloseEvent):void
{	
	if (np.gpxfilepath.text != "" && np.flvfilepath.text!="")
	{
		this.pdata.modify(np.flvfilepath.text, np.gpxfilepath.text, np.prjname.text, np.prjdesc.text);
	}
	PopUpManager.removePopUp(np);
}

public function fileOpenSelected(evt:Event):void
{
	CursorManager.setBusyCursor();	
	var f:File = File(evt.currentTarget);
	this.pdata = new ProjectData();
 	this.pdata.open(f, videoplayer);
 	this.pdata.addEventListener("PRJLoaded", projectLoaded);
 	this.pdata.addEventListener("TimeGapsFound", onTimeGapsDetected); 
}

public function projectLoaded(e:Event):void
{
	// Esperamos a que se inicialice el mapa si no lo ha hecho ya
	while (!map.isMapReady());	
		
	map.drawTrack();	
	
	// Enable buttons
	secback.enabled = true;
	secforw.enabled = true;
	selst.enabled = true;
	selcl.enabled = true;
	selall.enabled = true;
	playButton.enabled = true;
	videoslider.enabled = true;	
	videoslider.value = 0;
	smoothbtn.enabled = true;
	fixbtn.enabled = true;
	filterbtn.enabled = true;
	getelevation.enabled = true;
	profilevalues = this.pdata.getGISPointArrayCollection();
	gridvalues = this.pdata.getGridData();			
	timelineData.setItemAt({distance:0, elevation:this.pdata.getMinHeight()}, 0);
	timelineData.setItemAt({distance:0, elevation:this.pdata.getCurrentHeightFixed(0)}, 1);
	menuData.dataProvider[0].menuitem[2].@enabled=true;
	menuData.dataProvider[0].menuitem[3].@enabled=true;
	menuData.dataProvider[0].menuitem[4].@enabled=true;
	menuData.dataProvider[0].menuitem[5].@enabled=true;
	menuData.dataProvider[0].menuitem[5].menuitem[0].@enabled=true;
	menuData.dataProvider[0].menuitem[5].menuitem[1].@enabled=true;
	menuData.dataProvider[0].menuitem[5].menuitem[2].@enabled=true;
	menuData.dataProvider[0].menuitem[6].@enabled=true;	
	menuData.dataProvider[1].menuitem[0].@enabled=true;
	menuData.dataProvider[1].menuitem[1].@enabled=true;
	menuData.dataProvider[1].menuitem[2].@enabled=true;
		
	title = "RLV Forge - "+ pdata.getProjectName();
	// show info
	videoplayer.playheadTime = 0;
	this.elevAxis.minimum = this.pdata.getMinHeight();
	CursorManager.removeBusyCursor();
	this.pdata.addEventListener("PRJChanged", onPrjChange);
}
public function fileSaveSelected(evt:Event):void
{
	CursorManager.setBusyCursor();
	var file:File = evt.currentTarget as File;	
	if(file.extension  == null || file.extension!="prf")
    	file.nativePath += ".prf";

	this.pdata.save(file);
	CursorManager.removeBusyCursor();
	title = "RLV Forge - "+ pdata.getProjectName();
}

public function wayPointWindow_close(e:CloseEvent):void
{
	var gp:GISPoint = this.pdata.getCurrentGISPoint(this.videoplayer.playheadTime);	
	var wpe:WayPointEditor = e.currentTarget as WayPointEditor;
	if (wpe.type == "SEGSTART" )
	{
		if (wpe.wptname.text != "")
		{
			gp.setCommentType("SEGSTART:"+wpe.wptname.text);
			gp.setComment(wpe.description.text);
		}
	}
	if (wpe.type == "SEGEND")
	{	
		if (wpe.wptname.text != "")
		{
			gp.setCommentType("SEGEND:"+wpe.wptname.text);
			gp.setComment("");
		}
	}
	else if (wpe.type == "INFOBOX")
	{
		if (wpe.description.text != "")
		{
			gp.setCommentType("INFOBOX");
			gp.setComment(wpe.description.text);
		}
	}
	PopUpManager.removePopUp(wpe);
	this.videoplayer.refreshBuffers();
}

public function onVideoUpdate(e:VideoEvent):void
{
	// Si el mapa está listo actualizamos la posicion
	if (map.isMapReady())
	{
		var t:Number = videoplayer.playheadTime;
		if (map.isLoaded() && t<= this.pdata.getTotalTime())
		{			
			var cp:GISPoint = this.pdata.getCurrentGISPoint(t);
			if (cp!=null)		
				map.setMapPosition(cp.getLat(),cp.getLon());
		}
	}
	if (selstart!=-1)
	{
		var end:Number;
		if (selend != -1)			
			end = selend;
		else 
			end = Math.floor(videoplayer.playheadTime);
							 		
		seltime.text = Utils.formatTime((end - selstart)) + "s";
		selslope.value = this.pdata.getSlopeBetween(selstart, end);
		seldist.text = Utils.formatNumber(this.pdata.getDistanceBetween(selstart, end), 1) + "m";			
		videoplayer.updateSelection(selstart, end);
	}
	else
	{
		seltime.text = Utils.formatTime(0) + "s";
		selslope.value = 0;
		seldist.text = Utils.formatNumber(0, 1);
	}

	videoslider.value = videoplayer.playheadTime;
	if (datagrid!=null)
	{
		datagrid.selectedIndex = pdata.timeToIndex(videoplayer.playheadTime);
		datagrid.scrollToIndex(datagrid.selectedIndex);
		this.gridvalues.refresh();
	}
	/*if (int(videoplayer.playheadTime) % 10 == 0)
	{
		var d:Number = this.pdata.getCurrentDistance(videoplayer.playheadTime);
		timelineData.setItemAt({distance:d, elevation:this.pdata.getMinHeight()}, 0);
		timelineData.setItemAt({distance:d, elevation:this.pdata.getCurrentHeightFixed(videoplayer.playheadTime)}, 1);
	}*/	
}

public function vidStateChange(e:VideoEvent):void
{	
	if (e.state == VideoEvent.SEEKING)
	{		
		videoslider.enabled = false;
		CursorManager.setBusyCursor();		
	}
	else if (e.state == VideoEvent.PAUSED )
	{
		videoslider.enabled = true;
		CursorManager.removeBusyCursor();
		// Reubico la linea de posicion en el perfil		
		var d:Number = this.pdata.getCurrentDistance(videoplayer.playheadTime);
		//timelineData.setItemAt({distance:d, elevation:this.pdata.getMinHeight()}, 0);
		timelineData.setItemAt({distance:d, elevation:this.elevAxis.minimum}, 0);
		timelineData.setItemAt({distance:d, elevation:this.pdata.getCurrentHeightFixed(videoplayer.playheadTime)}, 1);
	}
	else if (e.state == VideoEvent.PLAYING)
	{
		CursorManager.removeBusyCursor();
		// Oculto la linea de posicion en el perfil para no confundir al usuario
		timelineData.setItemAt({distance:0, elevation:this.pdata.getMinHeight()}, 0);
		timelineData.setItemAt({distance:0, elevation:this.pdata.getMinHeight()}, 1);
	}	
}

public function onVideoComplete(e:VideoEvent):void
{
	trace(e.playheadTime);
	this.videoplayer.stop();
}

// Callback de botones de seleccion
private function selectionStart():void
{
	if (selst.selected)
	{
		if(this.selend == -1)				
			this.selstart = videoplayer.playheadTime;
		else			
			this.selstart = this.selend ;			
		this.selend = -1;
		selst.label = "Sel end";
		startPlaying();
	}
	else
	{
		this.selend = videoplayer.playheadTime;
		selst.label = "Sel start";
		pausePlaying();
	}
	videoplayer.updateSelection(selstart, selend);
}	

private function selectionClear():void
{
	selstart = -1;
	selend = -1;
	videoplayer.updateSelection(selstart, selend);
	pausePlaying();	
}

private function selectionAll():void
{
	selstart = 0;
	selend = this.pdata.getTotalTime();
	videoplayer.updateSelection(selstart, selend);
	pausePlaying();
	this.refreshGuiData();	
}

private function changeSelectionSlope():void
{
	if (selstart!=-1 && selend!=-1)
	{
		videoplayer.correctSelectedSlope(selslope.value);
		this.refreshGuiData();
	}
}

private function constSlopes():void
{
	//this.pdata.fixSlopes();
	this.pdata.constantSlope(Number(selslope.value));
	this.refreshGuiData();
}

private function applyBkoolFilters():void
{
	CursorManager.setBusyCursor();
	this.pdata.bkoolFilters();
	this.refreshGuiData();
	CursorManager.removeBusyCursor();
}

private function smoothSlopes():void
{
	CursorManager.setBusyCursor();
	this.pdata.smoothSlopes();
	this.refreshGuiData();
	CursorManager.removeBusyCursor();
}

private function getElevationFromGoogle():void
{
	this.pdata.setElevationFromGoogle(videoplayer.getSelectionStart(), videoplayer.getSelectionEnd());	
	// No hay necesidad de refrescar porque la llamada a google es asincrona
}

private function onPrjChange(e:Event):void
{
	this.map.refreshTrack();
	this.refreshGuiData();
}


// Funciones especificas del gráfico de perfil
public function slopeLabels(index:Number, prev:Number, axis:IAxis):String
{	
	var ret:String = "";
	if (this.pdata != null && 
		//index<this.pdata.getTotalPoints()-1 && 		
		index>=0 && 
		prev!=NaN && prev>=0)
	{						
		var avgslope:Number = this.pdata.getSlopeBetweenDistance(prev, index);	
		if (avgslope>-20)
			ret = Utils.formatNumber(index/1000,1)+ "\n" + Utils.formatNumber(avgslope,1)+"%";
		//trace("slopeLabels "+index+" prev="+prev+" mslope="+ret);	
	}
	return ret;	
}
public function timeLabels(index:Number, prev:Number, axis:IAxis):String
{	
	var ret:String = "";
	if (this.pdata != null && 
		index<this.pdata.getTotalPoints()-1 && 
		index>=0)
	{
		//var formater = new NumberFormatter();
		//formater.precision = 2;
		//return formater.format(this.pdata.getDistanceAt(index)/1000);
		return Utils.formatTime(index, false);		
	}		
	
	return ret;	
}

public function chartToolTip(data:HitData):String
{	
	var s:String = "";	
	if (data.element is AreaSeries)
	{		
		var dataElement:AreaSeries = AreaSeries(data.element);		
		s = "<B>" + dataElement.displayName + "</B>\n";
	  	s += "Distance: " + Math.round(data.item.distance) + " m\n";
	   	s += "Time: " + Utils.formatTime(data.item.time) + " \n";
		s += "Elevation: " + Math.round(data.item.elevation) + " m\n";
		s += "Slope: " + Utils.formatNumber(data.item.slope,1) + " %";			
	}
	else if (data.element is LineSeries)
	{		
		s = "Current position";		
	}
	return s	
}		

public function onChangeProfileScale(e:MouseEvent):void
{
	if (e.delta<0)
		elevAxis.minimum -= 25;
	else
		elevAxis.minimum += 25;
}

public function onClickOnProfile(e:MouseEvent):void
{	
	var data:HitData = AreaSeries(e.currentTarget).findDataPoints(e.localX, e.localY, 1)[0];
	if (data)
	{
		var idx:int = this.pdata.distanceToIndex(data.item.distance);
		this.videoplayer.playheadTime = this.pdata.getTimeAt(idx);
	} 	 
}


/**
 * Grid functions
 */

/**
 * Changes row color depending on current timemarker or excesive slope change
 */
public function calcRowColor(item:Object, rowIndex:int, dataIndex:int, color:uint):uint
{
    var newcolor:uint = color; 
    if(item.marker == true)   
 	  	newcolor = CURRENT_ROW_COLOR;
   	else if (dataIndex > 0 && 
   			Math.abs( this.pdata.getSlopeAt(dataIndex) - this.pdata.getSlopeAt(dataIndex-1)) > 4)
    	newcolor = HUGESLOPECHANGE_ROW_COLOR;
   	else if (dataIndex > 0 && 
   			Math.abs( this.pdata.getSlopeAt(dataIndex) - this.pdata.getSlopeAt(dataIndex-1)) > 2)
   		newcolor = MODERATESLOPECHANGE_ROW_COLOR; 
   	
   	if (dataIndex > 0 && Math.abs(this.pdata.getSlopeAt(dataIndex)) > 20)
   		newcolor = STEEPSLOPE_ROW_COLOR;
   		
   	if (dataIndex >= this.videoplayer.getSelectionStart() && dataIndex <= this.videoplayer.getSelectionEnd())
   		newcolor = SELECTED_ROW_COLOR;	  	
 	
 	return newcolor;
} 
 
public function gridClickHandler(evt: MouseEvent):void
{
	if (evt.currentTarget.selectedItem != null)
		this.videoplayer.playheadTime = evt.currentTarget.selectedItem.time;
}

public function gridDataChangeHandler(event:DataGridEvent):void
{	
	 // get a reference to the datagrid 
	 var grid:DataGrid = event.target as DataGrid; 
	 // get a reference to the name of the property in the 
	 // underlying object corresponding to the cell that's being edited 
	 var field:String = event.dataField; 
	 // get a reference to the row number (the index in the 
	 // dataprovider of the row that's being edited) 
	 var row:Number = Number(event.rowIndex);
	  // get a reference to the column number of 
	  // the cell that's being edited 
	  var col:int = event.columnIndex; 
	  if (grid != null) 
	  { 
	  	  // gets the value (pre-edit) from the grid's dataprovider 
	  	  var oldValue:Number = Number(grid.dataProvider.getItemAt(row)[field]); 
	  	  // you could also use the following line to get the value 
	  	  // directly from the cellrenderer that's showing the value 
	  	  // in the datagrid -- it's the same value. 
	  	  // That way you wouldn't need a reference to the DataGrid. 
	  	  //var oldValue = event.itemRenderer.data[field]; 
	  	  // get the value (post-edit) from the item editor 
	  	  var newValue:Number = Number(grid.itemEditorInstance[grid.columns[col].editorDataField]); 
	  	  // check if the value has changed 
	  	  if (newValue != oldValue) 
	  	  { 
	  	  	trace("changed row "+row+" col "+col);
	  	  	if (col==4)		// elevation
	  	  	{
	  	  		this.pdata.setElevAt(row,newValue);	  	  		  	  			  	  		
	  	  		this.videoplayer.refreshBuffers();	  	  		
	  	  	}
	  	  	else if (col==2)// latitude
	  	  	{  
	  	  		this.pdata.setLatAt(row, newValue);	  			  	  			  	  		  	  	
	  	  		this.map.refreshTrack();						
	  	  	}
	  	  	else if (col==3)// longitude
	  	  	{
				this.pdata.setLonAt(row, newValue);	
				this.map.refreshTrack();							  	  		
	  	  	}
	  	  	else if(col==1) // time
	  	  	{
	  	  		//this.pdata.setTimeAt(row, newValue);
	  	  	}
	  	  	this.pdata.recalculateProfile(row-1,row+1);
			refreshGuiData();
	  	  	// do actions that should happen when the data changes 
	  	  	// Note that in this case, the dataprovider 
	  	  	// hasn't been updated yet, so you can't do any 
	  	  	// actions that require the dataprovider to have 
	  	  	// the new data 
	  	  } 
	  }   
}

private function refreshGuiData():void
{
	profilevalues = this.pdata.getGISPointArrayCollection();
	gridvalues = this.pdata.getGridData();
	//datagrid.selectedIndex = pdata.timeToIndex(videoplayer.playheadTime);
	//datagrid.scrollToIndex(datagrid.selectedIndex);
	videoplayer.refreshBuffers();
	this.executeBindings();
} 

private function onTimeGapsDetected(event:Event):void
{
	var tgs:TimeGapSelector = new TimeGapSelector();
	tgs.dataSource = event.currentTarget.getTimeGaps();
	PopUpManager.addPopUp(tgs, this, true);
	PopUpManager.centerPopUp(tgs);
	tgs.addEventListener(CloseEvent.CLOSE, closeTimeGapSelector);
	tgs.addEventListener(mx.events.ListEvent.ITEM_CLICK, timeGapGridClicked);	
}


private function closeTimeGapSelector(ce:CloseEvent):void
{	
	PopUpManager.removePopUp(TimeGapSelector(ce.currentTarget));
	if (ce.detail == 1)
	{
		this.pdata.applyTimeCorrection();
	}	
}

private function timeGapGridClicked(event:ListEvent):void
{
	var timecorrection:Number = 0;
	var ds = event.currentTarget.dataSource;
	for (var i:Number=0; i<event.rowIndex; i++)
		if (ds[i].correct)
			timecorrection += ds[i].lenght;
	var time:Number = ds[event.rowIndex].departLap - timecorrection;
	videoplayer.playheadTime = time;
	if (map.isMapReady())
	{	
		if (map.isLoaded() && ds[event.rowIndex].departLap<= this.pdata.getTotalTime())
		{			
			var cp:GISPoint = this.pdata.getCurrentGISPoint(ds[event.rowIndex].departLap);
			if (cp!=null)		
				map.setMapPosition(cp.getLat(),cp.getLon());
		}
	}
}
